跨表引用的自动更新
If
e.DataCol.Name = "品名" Then '如果内容发生变动的是品名列可以实现在订单表中输入品名后,能自动从产品表中找出对应产品的单价,填入到单价列中。
如果修改某一个产品的单价,那么该产品原有订单的单价会保持不变,只有新增的订单才会使用新的单价,这和通过表达式列来引用产品单价是不同的。
可是也有一些场合,可能会要求修改产品单价后,原有订单的产品单价也自动更新。
为此,我们可以在产品表的DataColChanged事件中加入如下代码:
If
Dim
Filter As
String =
"[品名] = '" & e.DataRow("品名")
& "'"
Dim drs
As List(Of
DataRow)
= DataTables("订单").Select(Filter)
For Each dr
As DataRow
In drs
dr("单价")
= e.DataRow("单价")
Next
End
If
在产品表修改某个产品的单价后,上面的代码会找出订单表中该产品的所有订单,将这些订单的单价设置为新的单价。
我们还可以将前面的代码写得更为简洁:
If e.DataCol.Name = "单价"
Dim Filter
As String
= "[品名] = '"
&
e.DataRow("品名")
&
"'"
DataTables("订单").ReplaceFor("单价",
e.NewValue, Filter)
End If
不过我个人更喜欢第一种写法,虽然代码长了那么一点,但似乎也更容易理解那么一点。
再次提示一下,在上面的DataColChanged事件中,e.NewValue等于e.DataRow("单价"),因为此时新的单价已经写入表中。
所以下面这行代码:
DataTables("订单").ReplaceFor("单价", e.NewValue, Filter)
完全等效于:
DataTables("订单").ReplaceFor("单价", e.DataRow("单价"), Filter)
有条件的跨表更新
上面已经介绍了如何实现跨表引用的自动更新,可是更新有的时候是有条件的,否则还不如直接使用表达式列来引用产品单价。
例如希望在产品表中修改单价后,订单表中已经付款的订单,继续保持原单价不变,而未付款的订单采用新的单价。
为此,我们可以在产品表的DataColChanged事件中加入如下代码:
If e.DataCol.Name = "单价"
Dim Filter
As String
= "[品名] = '"
&
e.DataRow("品名")
&
"' And 已付款 = False"
DataTables("订单").ReplaceFor("单价",
e.NewValue, Filter)
End If
再例如希望在产品表中修改单价后,对于已经锁定或者已经付款的订单,单价保持不变,其余订单则采用新的单价:
If e.DataCol.Name
= "单价"
Dim Filter
As String
= "[品名] = '"
&
e.DataRow("品名")
&
"' And 已付款 = False"
Dim drs
As List(Of
DataRow)
= DataTables("订单").Select(Filter)
For Each dr
As DataRow
In drs
If
dr.Locked = False Then
DataTables("订单").DataCols("品名").RaiseDataColChanged(dr)
End If
Next
End If
多列跨表更新
如果订单表有多列数据来自于产品表,一样可以采用类似的设计实现跨表更新。
例如,假定产品表和订单表通过产品编号联系起来(不一定建立了关联),订单表输入产品编号后,品名、型号、规格、单价四列内容从产品表自动继承输入。
为实现此目的,首先订单表的DataColChanged事件代码应设置为:
If
e.DataCol.Name = "产品编号" Then现在希望在产品表修改上述四列数据后,订单表能够自动更新这些列的数据,为此可以将产品表的DataColChanged事件设置为:
Select
Case e.DataCol.Name或者:
Select
Case e.DataCol.Name
Case
"品名","型号","规格","单价"
Dim Filter
As
String =
"[产品编号] = '" & e.DataRow("产品编号")
& "'"
DataTables("订单").ReplaceFor(e.DataCol.Name,
e.NewValue,
Filter)
End
Select
可以看到不管是单列还是多列,自动更新的代码都一样的简洁。
关联表下的编码
不管是产品表和订单表之间是否建立了关联,本节之前所讲述的代码,均是适用的。
如果产品表和订单表之间已经建立了关联,那么代码可以写得稍微简洁一些,因为可以用GetChildRows获得某个产品的所有订单,用GetParentRow获得某个订单对应的产品。
示例
假定产品表和订单表通过产品编号建立了关联,订单表输入产品编号后,品名、型号、规格、单价四列内容从产品表自动继承输入。
为实现此目的,首先订单表的DataColChanged事件代码应设置为:
If
e.DataCol.Name = "产品编号" Then现在希望在产品表修改上述四列数据后,订单表能够自动更新这些列的数据,为此可以将产品表的DataColChanged事件设置为:
Select
Case e.DataCol.Name上面的代码只是作为多列继承的一个例子而已,因为既然已经建立了关联,那么对于订单表中那些始终和产品表对应列内容保持一直的列,如品名、型号、规格等列,显然用表达式列更为合适;通常只有单价这种可能和产品表对应列内容有差异的列,才会考虑使用数据列,通过代码来计算的。